package com.zcoj.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zcoj.core.model.ApiResponse;
import com.zcoj.core.model.PageData;
import com.zcoj.core.model.PageWrap;
import com.zcoj.mapper.TrainingMapper;
import com.zcoj.mapper.TrainingProblemMapper;
import com.zcoj.mapper.TrainingRegisterMapper;
import com.zcoj.pojo.Dto.Training;
import com.zcoj.pojo.Dto.TrainingProblem;
import com.zcoj.pojo.Dto.TrainingRegister;
import com.zcoj.pojo.Vo.TrainingAuthVo;
import com.zcoj.security.dto.LoginUser;
import com.zcoj.service.TrainingProblemService;
import com.zcoj.service.TrainingService;
import com.zcoj.util.RedisCaches;
import com.zcoj.util.WrapperUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * Service实现
 * @author 剩xia的盛夏
 * @date 2023/02/24 16:16
 */
@Service
@Slf4j
public class TrainingServiceImpl implements TrainingService {

    @Autowired
    private TrainingMapper trainingMapper;

    @Autowired
    private TrainingProblemMapper trainingProblemMapper;

    @Autowired
    private TrainingProblemService trainingProblemService;

    @Autowired
    private TrainingRegisterMapper trainingRegisterMapper;

    @Autowired
    private RedisCaches redisCaches;

    @Override
    public Integer create(Training training) {
        LoginUser loginUser = redisCaches.getLoginUser();
        if(Objects.isNull(training)) {
            return 0;
        }
        training.setAuthor(loginUser.getUsername());
        trainingMapper.insert(training);
        return training.getId();
    }

    @Override
    public Integer deleteById(Integer id) {
        QueryWrapper<TrainingProblem> trainingProblemQueryWrapper=new QueryWrapper<>();
        trainingProblemQueryWrapper.eq("tid",id);
        List<TrainingProblem> trainingProblems = trainingProblemMapper.selectList(trainingProblemQueryWrapper);
        List<Integer> list=new ArrayList<>();

        for (TrainingProblem trainingProblem : trainingProblems) {
            trainingProblemService.deleteById(trainingProblem.getId());
        }


        return trainingMapper.deleteById(id);
    }

    @Override
    public void deleteByIdInBatch(List<Integer> ids) {
        if (CollectionUtils.isEmpty(ids)) return;
        trainingMapper.deleteBatchIds(ids);
    }

    @Override
    public Integer updateById(Training training) {
        if(Objects.nonNull(training.getAuth())){
            if(training.getAuth()==2){
                if(Objects.isNull(training.getPrivatePwd())){
                    return 0;
                }
            }
        }
        return trainingMapper.updateById(training);
    }

    @Override
    public void updateByIdInBatch(List<Training> trainings) {
        if (CollectionUtils.isEmpty(trainings)) return;
        for (Training training: trainings) {
            this.updateById(training);
        }
    }

    @Override
    public Training findById(Integer id) {
        return trainingMapper.selectById(id);
    }

    @Override
    public Training findOne(Training training) {
        Wrapper<Training> wrapper = new QueryWrapper<>(training);
        return trainingMapper.selectOne(wrapper);
    }

    @Override
    public List<Training> findList(Training training) {
        Wrapper<Training> wrapper = new QueryWrapper<>(training);
        return trainingMapper.selectList(wrapper);
    }
  
    @Override
    public PageData<Training> findPage(PageWrap<Training> pageWrap) {
        IPage<Training> page = new Page<>(pageWrap.getPage(), pageWrap.getCapacity());
        Training training = WrapperUtil.blankToNull(pageWrap.getModel());
        QueryWrapper<Training> queryWrapper = new QueryWrapper<>();
        for(PageWrap.SortData sortData: pageWrap.getSorts()) {
            if (sortData.getDirection().equalsIgnoreCase("DESC")) {
                queryWrapper.orderByDesc(sortData.getProperty());
            } else {
                queryWrapper.orderByAsc(sortData.getProperty());
            }
        }
        if(Objects.nonNull(training.getTitle())){
            queryWrapper.like("title",training.getTitle());
        }
        if(Objects.nonNull(training.getAuth())){
            queryWrapper.eq("auth",training.getAuth());
        }
        if(Objects.nonNull(training.getCategory())){
            queryWrapper.eq("category",training.getCategory());
        }
        if(Objects.nonNull(training.getStatus())){
            queryWrapper.eq("status",training.getStatus());
        }
        queryWrapper.select("id","title","author","auth","category","status","create_time","update_time");
        return PageData.from(trainingMapper.selectPage(page, queryWrapper));
    }

    @Override
    public PageData<Training> findPageVo(PageWrap<Training> pageWrap) {
        LoginUser loginUser = redisCaches.getLoginUser();
        IPage<Training> page = new Page<>(pageWrap.getPage(), pageWrap.getCapacity());
        Training training = WrapperUtil.blankToNull(pageWrap.getModel());

        QueryWrapper<Training> queryWrapper = new QueryWrapper<>();
        if(Objects.nonNull(training.getAuth())&&training.getAuth()!=0){
            queryWrapper.eq("auth",training.getAuth());
        }

        if(Objects.nonNull(training.getCategory())&&training.getCategory()!=0){
            queryWrapper.eq("category",training.getCategory());
        }

        if(Objects.nonNull(training.getTitle())){
            queryWrapper.like("title",training.getTitle());
        }

        if(Objects.nonNull(training.getStatus())){
            queryWrapper.eq("status",training.getStatus());
        }

        for(PageWrap.SortData sortData: pageWrap.getSorts()) {
            if (sortData.getDirection().equalsIgnoreCase("DESC")) {
                queryWrapper.orderByDesc(sortData.getProperty());
            } else {
                queryWrapper.orderByAsc(sortData.getProperty());
            }
        }
        queryWrapper.select("id","title","author","auth","category","create_time");

        return PageData.from(trainingMapper.selectPage(page, queryWrapper));
    }

    @Override
    public long count(Training training) {
        Wrapper<Training> wrapper = new QueryWrapper<>(training);
        return trainingMapper.selectCount(wrapper);
    }

    @Override
    public ApiResponse getTrainingAuth(TrainingAuthVo trainingAuthVo) {
        trainingAuthVo=WrapperUtil.blankToNull(trainingAuthVo);
        String redisAuthKey="trainingRegisterTid_" + trainingAuthVo.getTid();
        Map<String, String> map=new HashMap<>();
        String redisAuthValue = redisCaches.getCacheObject(redisAuthKey);
        //从redis取
        if(Objects.nonNull(redisAuthValue)){
            map.put("auth","1");
            return ApiResponse.success(JSON.toJSON(map));
        }

        log.info(trainingAuthVo.toString());
        Training training = trainingMapper.selectById(trainingAuthVo.getTid());
        log.info(training.toString());
        if(Objects.isNull(training)){
            return ApiResponse.failed("训练不存在");
        }else {
            if (training.getAuth()==1){
                map.put("auth","1");
                redisCaches.setCacheObject(redisAuthKey,"1",12, TimeUnit.HOURS);
            }else {
                QueryWrapper<TrainingRegister> queryWrapper=new QueryWrapper<>();
                queryWrapper.eq("tid",trainingAuthVo.getTid()).eq("uid",trainingAuthVo.getUid());
                TrainingRegister trainingRegister = trainingRegisterMapper.selectOne(queryWrapper);
                if(Objects.nonNull(trainingRegister)&&!trainingRegister.getStatus()){
                    return ApiResponse.failed("用户封禁！！！联系训练管理员");
                }
                //为空 与密码匹配
                if(Objects.isNull(trainingRegister)){
                    if(Objects.nonNull(trainingAuthVo.getPassword())){
                        if(training.getPrivatePwd().equals(trainingAuthVo.getPassword())){
                            TrainingRegister register = new TrainingRegister();
                            register.setStatus(true);
                            register.setUid(trainingAuthVo.getUid());
                            register.setTid(trainingAuthVo.getTid());
                            int insert = trainingRegisterMapper.insert(register);
                            if(insert==1){
                               map.put("auth","1");
                            }
                        }else {
                            return ApiResponse.failed("训练密码错误!!!");
                        }
                    }else {
                        map.put("auth","2");
                    }
                }else {
                    map.put("auth","1");
                }
            }
            return ApiResponse.success(JSON.toJSON(map));
        }
    }
}
